﻿
#include <iostream>
#include "../../win_com/xx_hardwre_bp_hook.hpp"
#include "../../win_com/xx_mem.hpp"
#include "../../win_com/xx_hook_trampoline.hpp"

void func()
{
	printf("xxx1");
}

void test_exe_hw_bp_func() {
	xx_set_hw_bp(GetCurrentThread(),1, &func, RW_EXE);
	func();
}

void test_write_hw_bp() {
	int n = 0;
	xx_set_hw_bp(GetCurrentThread(), 0, &n, RW_WRITE);

	n = 1;//write
}

void test_read_hw_bp() {
	int n = 0;
	xx_set_hw_bp(GetCurrentThread(), 0, &n, RW_RW);
	int b = n;//read

	b = b * b;

	n = 5;
}

void test_vs_data_bp() {
	int n = 0;
	CONTEXT context = { 0 };
	context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
	auto ret = GetThreadContext(GetCurrentThread(), &context);

	xx_dr7 dr7{ 0 };
	dr7.set(context.Dr7);
}

void test_write_hw_bp_1byte() {
	char c[4];

	xx_set_hw_bp(GetCurrentThread(), 0, c, RW_WRITE,LEN_1B);
	c[0] = 0;
	c[1] = 0;

	xx_set_hw_bp(GetCurrentThread(), 0, c, RW_WRITE, LEN_4B);
	c[0] = 0;
	c[1] = 0;
}

void test_read_hw_bp_1byte() {
	char c[4];
	xx_set_hw_bp(GetCurrentThread(), 0, c, RW_RW, LEN_1B);

	char temp = c[0];
	temp = c[1];
}

void test_dr7() {
	test_vs_data_bp();
	//test_exe_hw_bp_func();
	test_write_hw_bp();
	test_read_hw_bp();

	test_write_hw_bp_1byte();
	test_read_hw_bp_1byte();
}
////////////////////////////////////////////////////////
// 
// Defined values for the exception filter expression
//#define EXCEPTION_EXECUTE_HANDLER      1
//#define EXCEPTION_CONTINUE_SEARCH      0
//#define EXCEPTION_CONTINUE_EXECUTION (-1)
static LONG NTAPI xx_veh_handler(struct _EXCEPTION_POINTERS* ExceptionInfo)
{
	xx_dr6 dr6;
	dr6.set(ExceptionInfo->ContextRecord->Dr6);
	return EXCEPTION_CONTINUE_EXECUTION;
}

void test_dr6() {
	xx_add_veh(CALL_FIRST, xx_veh_handler);
	test_exe_hw_bp_func();
}
////////////////////////////////////////////////////////
char trampoline[1024];


int WINAPI My_MessageBoxA(
	_In_opt_ HWND hWnd,
	_In_opt_ LPCSTR lpText,
	_In_opt_ LPCSTR lpCaption,
	_In_ UINT uType)
{
	printf("[call %s]!\n", __FUNCTION__);

	auto ori = xx_trampoline_to_func(&MessageBoxA, trampoline);
	return (*ori)(hWnd, lpText, lpCaption, uType);
}

void test_hook() {

	// 制作跳板，只需要复制1条指令，跳过硬件断点即可
	xx_mem_unprotect(trampoline, 1024);
	xx_make_trampoline(&MessageBoxA, trampoline, 4);

	xx_init_hwbp_hook();
	g_hwbp_.hook(&MessageBoxA, &My_MessageBoxA,GetCurrentThread(), 0);
	::MessageBoxA(0, "aaa", "bbb", 0);
}

int main()
{
	//test_dr7();
	//test_dr6();
	test_hook();

	return 0;
}


